package com.academicsystem.www.service.impl;

import com.academicsystem.www.constant.Constant;
import com.academicsystem.www.dao.Dao;
import com.academicsystem.www.model.Graph;
import com.academicsystem.www.model.Lesson;
import com.academicsystem.www.model.Major;
import com.academicsystem.www.model.SettingLesson;
import com.academicsystem.www.service.Service;
import com.academicsystem.www.utils.GraphUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jacky
 */
@org.springframework.stereotype.Service
public class ServiceImpl implements Service {
    @Autowired
    private Dao dao;

    @Override
    public List<Major> getMajorTable(){
        return dao.getMajorTable();
    }

    @Override
    public List<Lesson> getLessonList(Integer majorId) {
        return dao.getLessonByMajor(majorId);
    }

    @Override
    public Graph showGraph(Integer majorId){
        List<Lesson> lessons = dao.getLessonByMajor(majorId);
        Graph graph = new Graph();
        for(Lesson lesson:lessons){
            GraphUtils.addVertex(graph.getVertexes(),lesson.getId());
            List<Integer> beforeLessonIds = dao.getBeforeLessonId(lesson.getId());
            for(Integer beforeLessonId:beforeLessonIds){
                GraphUtils.addEdge(graph.getVertexes(),beforeLessonId,lesson.getId());
            }
        }
        return graph;
    }

    @Override
    public List<Lesson> makePlan(Integer majorId,double limitCredit){
        List<Lesson> plan = new ArrayList<>();
        Integer term = 1;
        double currentCredit = 0;
        //Integer currentCount = 0;
        //Integer lessonCount = dao.getLessonCount(majorId);
        //Integer limitLessonCount = lessonCount % Constant.TERM_COUNTS > 0 ? lessonCount/Constant.TERM_COUNTS+1 : lessonCount/Constant.TERM_COUNTS;
        Graph graph = showGraph(majorId);
        List<Integer> lessonIds = GraphUtils.topologicalSort(graph.getVertexes());
        System.out.println(lessonIds);
        for(Integer lessonId:lessonIds){
            Lesson lesson = dao.getLessonById(lessonId);
            currentCredit += lesson.getCredit();
            //currentCount++;
            if(currentCredit > limitCredit /*|| currentCount > limitLessonCount*/){
                term++;
                currentCredit = lesson.getCredit();
                //currentCount = 1;
            }
            dao.addTerm(lessonId,term);
            plan.add(lesson);
        }
        return plan;
    }

    @Override
    public Integer addMajor(String majorName) {
        dao.addMajor(majorName);
        return dao.getMajorId(majorName);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMajor(List<Major> majors) {
        for(Major major:majors){
            dao.deleteMajor(major.getId());
            List<Lesson> lessons = dao.getLessonByMajor(major.getId());
            for(Lesson lesson:lessons){
                dao.deleteRelByLesson(lesson.getId());
            }
            dao.deleteLessonByMajor(major.getId());
        }
    }

    @Override
    public void addLesson(Lesson lesson) {
        dao.addLesson(lesson);
    }

    @Override
    public List<Lesson> getLessonExcept(Integer lessonId, Integer majorId) {
        return dao.getLessonExcept(lessonId, majorId);
    }

    @Override
    public void addBefore(SettingLesson settingLesson) {
        for(Lesson beforeLesson:settingLesson.getBeforeLessons()){
            dao.setBeforeLesson(settingLesson.getLessonId(), beforeLesson.getId());
        }
    }
}
